/* 

给定一个只包含数字的字符串，用以表示一个 IP 地址，返回所有可能从 ipString 获得的 有效 IP 地址 。你可以按任何顺序返回答案。

有效 IP 地址 正好由四个整数（每个整数位于 0 到 255 之间组成，且不能含有前导 0），整数之间用 '.' 分隔。

例如："0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址，但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。

 

示例 1：

输入：s = "25525511135"
输出：["255.255.11.135","255.255.111.35"]
示例 2：

输入：s = "0000"
输出：["0.0.0.0"]
示例 3：

输入：s = "1111"
输出：["1.1.1.1"]
示例 4：

输入：s = "010010"
输出：["0.10.0.10","0.100.1.0"]
示例 5：

输入：s = "101023"
输出：["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/restore-ip-addresses
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

*/

/**
 * @param {string} ipString
 * @return {string[]}
 */
var restoreIpAddresses = function (ipString) {
    const SEG_COUNT = 4;
    const segments = new Array(SEG_COUNT);
    const result = [];

    const dfs = (ipString, segId, segStart) => {
        // 如果找到了 4 段 IP 地址并且遍历完了字符串，那么就是一种答案
        // 如果找到了 4 段 IP 地址但是字符串还没遍历完，回溯
        if (segId === SEG_COUNT) {
            if (segStart === ipString.length) {
                result.push(segments.join('.'));
            }
            return;
        }

        // 如果还没有找到 4 段 IP 地址就已经遍历完了字符串，那么提前回溯
        if (segStart === ipString.length) {
            return;
        }

        // 由于不能有前导零，如果当前数字为 0，那么这一段 IP 地址只能为 0
        if (ipString.charAt(segStart) === '0') {
            segments[segId] = 0;
            dfs(ipString, segId + 1, segStart + 1);
        }

        // 一般情况，枚举每一种可能性并递归
        let addr = 0;
        for (let segEnd = segStart; segEnd < ipString.length; ++segEnd) {
            addr = addr * 10 + (ipString.charAt(segEnd) - '0');
            if (addr > 0 && addr <= 0xFF) {
                segments[segId] = addr;
                dfs(ipString, segId + 1, segEnd + 1);
            } else {
                break;
            }
        }
    }

    dfs(ipString, 0, 0);
    return result;
};